# !/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@author: JHC000abc@gmail.com
@file: route_auth.py
@time: 2024/11/5 20:18 
@desc: 

"""
import os
from config import SQLPAGESIZE
from sdk.utils.util_class import PathParser
from sdk.utils.util_encrypt import EncryptProcess
from werkzeug.utils import secure_filename
from flask.blueprints import Blueprint
from flask import request, jsonify, render_template
from db.model import UserInfo, STATUS_NORMAL, STATUS_DORBIDDEN, Token, STATUS_TOKEN_NORMAL, STATUS_TOKEN_DORBIDDEN
from .base_blue import auth, get_result_tmp, redis, jh_sk, jh_ak, sdb, auth_manager
from errors.msg import USER, TOKEN, LOGIN, SQL, PASSWORD

auth_blue = Blueprint('auth_blue', __name__)


@auth_blue.route('/login', methods=['POST', 'GET'])
def login():
    """

    :return:
    """
    result = get_result_tmp()
    if request.method == "GET":
        return render_template('login.html')
    # 获取请求中的 JSON 数据
    json_data = request.json
    user_name = json_data.get('username')
    password = json_data.get('password')

    # 校验用户名和密码是否为空
    if not user_name or not password:
        result["msg"] = USER["2"].format(user_name, password)
        return jsonify(result)

    # 查询数据库，获取用户信息
    user_record = sdb.select(UserInfo, {"user_name": user_name})

    # 检查用户是否存在
    if not user_record:
        result["msg"] = USER["2"].format(user_name, password)
        return jsonify(result)

    uni_user_info = user_record[0]
    # 校验用户状态是否正常
    if uni_user_info.status != STATUS_NORMAL:
        result["msg"] = USER["3"].format(user_name)
        return jsonify(result)

    # 校验密码是否正确
    if not jh_sk.verify_hash_code(password, uni_user_info.password):
        result["msg"] = USER["2"].format(user_name, password)
        return jsonify(result)

    # 创建 token
    user_info = {
        "user_name": user_name,
        "id": uni_user_info.id,
        "status": uni_user_info.status
    }
    jwt_token = jh_sk.create_token(data=user_info)
    jwt_token_ak = jh_ak.create_token(data=user_info)

    # token 表 更新旧记录 插入新记录
    update_sql = f"update token set status='{STATUS_TOKEN_DORBIDDEN}' where `user_id` = {uni_user_info.id} and `status` = '{STATUS_NORMAL}'"
    sdb.update(sql=update_sql)

    conditions = [
        {
            "user_id": uni_user_info.id,
            "token": jwt_token_ak
        }
    ]
    if sdb.insert(Token, conditions) is None:
        result["msg"] = TOKEN["4"].format(jwt_token_ak)
        return jsonify(result)

    result["status"] = 0
    result["code"] = "Success"
    result["results"] = {"token": jwt_token, "ak": jwt_token_ak}
    return jsonify(result)


@auth_blue.route('/logout', methods=['POST'])
@auth
def logout(*args, **kwargs):
    """

    :return:
    """
    result = get_result_tmp()
    # 已经验证过cookies
    client_cookie = kwargs["cookies"]
    user_info = kwargs["user_info"]
    # 放进redis队列
    redis.add_token_redis(client_cookie)

    update_sql = f"update token set status='{STATUS_TOKEN_DORBIDDEN}' where `user_id` = {user_info.id} and `status` = '{STATUS_NORMAL}'"
    sdb.update(sql=update_sql)

    result["msg"] = LOGIN["1"].format(user_info.user_name)
    result["status"] = 0
    result["code"] = "Success"
    return jsonify(result)


@auth_blue.route('/refresh', methods=['POST'])
def refresh(**kwargs):
    """

    :return:
    """
    result = get_result_tmp()
    client_cookie_ak = request.headers.get("Authorization").split(" ")[-1]
    try:
        verify_token = jh_ak.decrypt_token(token=client_cookie_ak)
    except:
        result["msg"] = TOKEN["5"]
        return jsonify(result)
    if not verify_token:
        result["msg"] = TOKEN["1"].format(client_cookie_ak)
        return jsonify(result)
    data = jh_ak.parse_token(token=client_cookie_ak)
    user_record = sdb.select(UserInfo, {"user_name": data["user_name"], "id": data["id"]})
    if not user_record:
        result["msg"] = USER["4"].format(data["user_name"])
        return jsonify(result)

    uni_user_info = user_record[0]
    # 校验用户状态是否正常
    if uni_user_info.status != STATUS_NORMAL:
        result["msg"] = USER["3"].format(data["user_name"])
        return jsonify(result)

    condition = {
        "user_id": data["id"],
        "status": STATUS_TOKEN_NORMAL
    }
    select_token_results = sdb.select(Token, condition)
    if not select_token_results:
        result["msg"] = TOKEN["2"].format(client_cookie_ak)
        return jsonify(result)

    new_ak = jh_sk.create_token(data=data)
    result["msg"] = TOKEN["6"].format(new_ak)
    result["status"] = 0
    result["code"] = "Success"
    result["results"] = {
        "token": new_ak,
    }
    return jsonify(result)


@auth_blue.route('/register', methods=['POST'])
@auth_manager
def register(*args, **kwargs):
    """

    :return:
    """
    result = get_result_tmp()
    json_data = request.json
    login_user_info = kwargs['user_info']
    user_name = json_data.get('username')
    password = json_data.get('password')
    user_type = json_data.get('grade', "0")
    if not user_name or not password:
        result["msg"] = USER["2"].format(user_name, password)
        return jsonify(result)
    # 查询数据库，获取用户信息
    user_record = sdb.select(UserInfo, {"user_name": user_name})
    # 检查用户是否存在
    if user_record:
        result["msg"] = USER["5"].format(user_name)
        return jsonify(result)
    # 确保只能插入级别更低的账户
    if int(user_type) > int(login_user_info.grade):
        result["msg"] = USER["6"].format(user_name, user_type)
        return jsonify(result)
    user_conditions = [{"user_name": user_name, "password": jh_sk.get_hash_code(password), "grade": str(user_type),
                        "superior": login_user_info.id}]
    res = sdb.insert(UserInfo, user_conditions)
    if res:
        result["msg"] = SQL["0"].format(user_conditions)
        result["status"] = 0
        result["code"] = "Success"
        return jsonify(result)
    else:
        result["msg"] = SQL["1"].format(res)
        return jsonify(result)


@auth_blue.route('/delete', methods=['POST'])
@auth_manager
def delete(*args, **kwargs):
    """

    :return:
    """
    result = get_result_tmp()
    json_data = request.json
    login_user_info = kwargs['user_info']
    user_name = json_data.get('username')

    if not user_name:
        result["msg"] = USER["2"].format(user_name)
        return jsonify(result)
    # 查询数据库，获取用户信息
    user_record = sdb.select(UserInfo, {"user_name": user_name})
    # 检查用户是否存在
    if not user_record:
        result["msg"] = USER["4"].format(login_user_info.user_name)
        return jsonify(result)
    db_user_info = user_record[0]

    if int(db_user_info.grade) >= int(login_user_info.grade):
        result["msg"] = USER["6"].format(login_user_info.user_name, login_user_info.grade)
        return jsonify(result)
    if db_user_info.status != STATUS_NORMAL:
        result["msg"] = USER["7"].format(login_user_info.user_name)
        return jsonify(result)
    if sdb.update(UserInfo, [{"user_name": user_name, "id": db_user_info.id, 'status': STATUS_DORBIDDEN}]) <= 0:
        result["msg"] = USER["8"].format(login_user_info.user_name)
        return jsonify(result)
    if login_user_info.user_name == user_name:
        client_cookie = kwargs["cookies"]
        redis.add_token_redis(client_cookie)

    update_sql = f"update token set status='{STATUS_TOKEN_DORBIDDEN}' where `user_id` = {login_user_info.id} and `status` = '{STATUS_NORMAL}'"
    sdb.update(sql=update_sql)

    result["msg"] = USER["9"].format(login_user_info.user_name)
    result["status"] = 0
    result["code"] = "Success"
    return jsonify(result)


@auth_blue.route('/modify/password', methods=['POST'])
@auth
def modify_password(*args, **kwargs):
    """

    :return:
    """
    result = get_result_tmp()
    json_data = request.json
    login_user_info = kwargs['user_info']
    cookies = kwargs['cookies']
    password = json_data.get('password')

    if not password:
        result["msg"] = PASSWORD["0"]
        return jsonify(result)
    user_name = login_user_info.user_name
    id = login_user_info.id
    try:
        db_update_result = sdb.update(UserInfo,
                                      [{"user_name": user_name, "password": jh_sk.get_hash_code(password), "id": id}])
        if not db_update_result:
            raise
    except:
        result["msg"] = PASSWORD["2"].format(password)
        return jsonify(result)

    redis.add_token_redis(cookies)

    update_sql = f"update token set status='{STATUS_TOKEN_DORBIDDEN}' where `user_id` = {login_user_info.id} and `status` = '{STATUS_NORMAL}'"
    sdb.update(sql=update_sql)

    result["status"] = 0
    result["code"] = "Success"
    result["results"] = db_update_result

    return jsonify(result)


@auth_blue.route('/upload', methods=['POST'])
@auth
def upload_file(*args, **kwargs):
    """

    :return:
    """
    if 'file' not in request.files:
        return "没有文件部分"

    file = request.files['file']

    if file.filename == '':
        return "没有选择文件"

    filename = secure_filename(file.filename)

    # 在这里，你可以确保文件名以 UTF-8 编码
    try:
        filename = filename.encode('utf-8').decode('utf-8')  # 处理编码
    except UnicodeEncodeError:
        return '文件名编码错误'

    # 处理文件（保存或其他操作）
    ep = EncryptProcess()
    tmp_path_upload = "tmp/uploads"
    os.makedirs(tmp_path_upload, exist_ok=True)
    file_name = PathParser(file.filename)
    save_name = f"{ep.make_uuid()}.{file_name.tail}"
    save_file = f"{tmp_path_upload}/{save_name}"
    file.save(save_file)

    return save_name


@auth_blue.route('/search/users', methods=['POST'])
@auth_manager
def search_user(*args, **kwargs):
    """

    :return:
    """
    result = get_result_tmp()
    json_data = request.json
    page = json_data.get('page', 0)
    more_info = {}
    try:
        db_search_results = sdb.select(model=UserInfo, conditions={}, offset=page)
        db_search_result = db_search_results["result"]
        more_info = {
            "all_nums": db_search_results["all_nums"],
            "page_size": db_search_results["page_size"],
            "page": db_search_results["page"],
        }
    except:
        result["msg"] = "user select failed"
        return jsonify(result)

    if not db_search_result:
        result["msg"] = "user select result is empty"
        return jsonify(result)
    select_results = []
    for db_user_info in db_search_result:
        select_results.append({
            "id": db_user_info.id,
            "user_name": db_user_info.user_name,
            "grade": db_user_info.grade,
            "superior": db_user_info.superior,
            "status": db_user_info.status,
        })
    if len(select_results) != SQLPAGESIZE:
        result["msg"] = f"End Page"
    else:
        result["msg"] = f"select success"

    result["status"] = 0
    result["code"] = "Success"
    result["results"] = {
        "result": select_results,
        "more_info": more_info
    }

    return jsonify(result)
